/* 
 * File:   FileNode.h
 * Author: KENNJI
 *
 * Created on March 22, 2013, 4:25 PM
 */
#include<stdio.h>
#include<string.h>

#include "../log/LoggerManager.h"
#include "../log/ConsoleLogger.h"

typedef char* (*PF_Traverse)();

extern LoggerManager* g_logger;

#ifndef ZIPNODE_H
#define	ZIPNODE_H

/**
 *Class to store data using recursive nodes
 */
class ZipNode
{
    /**
     * This defines the default size of branches
     */
#define DEFAULT_SIZE 10

public:
    /**
     * Instantiate a Recursive node
     * @param name The name of current node
     */
    ZipNode(const char* name);

    /**
     * Instantiate a Recursive node
     */
    ZipNode();

    /**
     * Constructor copy
     */
    ZipNode(const ZipNode& other);

    /**
     * Free the allocated memory used to store the branches
     * of current node 
     */
    virtual ~ZipNode();

    /**
     * Add a node to the branches
     * @param node The node that will be added to the branches
     */
    void addNode(ZipNode* node);


    /**
     * Checks if the name of node already exists in this node and their branches
     * @param nodeName The name of node that will be check if exists
     * @return true if node already exists, false other case
     */
    bool contains(const char* nodeName)const;

    /**
     * Browse the specific node in this node and their branches
     * @param name The name of node that will be browse
     * @return the node that contains that name, other case NULL
     */
    ZipNode* browse(const char* name);

    /**
     * Prints the name of current node
     */
    void traverse(PF_Traverse traverseFunction);
    /**
     * Remove an element of the nodes
     * @param element Name of node that will be removed
     */
    void remove(const char* element);

    /**
     * Get the branches of current node
     * @return The Branches of current node
     */
    ZipNode* getBranches()const;

    /**
     * Get the root name of current node
     * @return The root name of current node 
     */
    char* getRoot()const;

    /**
     * Set the root name of current node
     * @param rootToRplc Name of node to replace
     */
    void setRoot(const char* rootToPlc);

    /**
     * Check if this node is an instance of DirectoryNode or FileNode
     * @return true if is an instance of FileNode, other case false
     */
    virtual bool isLeaf() const = 0;

    /**
     * Get the branches size of current node
     * @return The branches size of current node
     */
    int size() const;

    void operator=(const ZipNode& orig);

private:
    bool containsInNode(const char* orig) const;

    void resizeBranches();

protected:
    /**
     * Define the branches of current node
     */
    ZipNode* branches_;
    /**
     * The root name of current node
     */
    char* root_;
    /**
     * The size of branches
     */
    int branchCounter_;
    /**
     * The available size of branches
     */
    int currentBranches_;
};


#endif	/* ZIPNODE_H */

